from __future__ import annotations
from typing import Iterator, Tuple
from google.protobuf.descriptor_pb2 import DescriptorProto, FieldDescriptorProto, FileDescriptorProto

from .utils import replace_suffix
from .options import Options


class ProtoFile:
    def __init__(self, fd: FileDescriptorProto, opts: Options):
        self.fd = fd
        self.opts = opts

    @property
    def package_name(self) -> str:
        return self.fd.package

    @property
    def file_basename(self) -> str:
        return self.fd.name.rstrip(".proto").replace("/", "_").replace(" ", "_").replace(".", "_")

    @property
    def cc_header_guard(self) -> str:
        # 例：foo/bar.proto -> FOO_BAR_NAPI_H_
        return replace_suffix(self.fd.name.replace("/", "_"), ".proto", "_napi_h").replace(".", "_").upper()

    @property
    def cc_module_name(self) -> str:
        # 例：foo/bar.proto -> foo/bar.pb.h
        return replace_suffix(self.fd.name, ".proto", ".pb.h")

    @property
    def cc_napi_name(self) -> str:
        # 例：foo/bar.proto -> foo/bar.napi.h
        return replace_suffix(self.fd.name, ".proto", ".napi.h")

    @property
    def cc_dts_name(self) -> str:
        # 例：foo/bar.proto -> foo/bar.d.ts
        return replace_suffix(self.fd.name, ".proto", "_pb.d.ts")

    def iter_extensions(self) -> Iterator[Tuple[FieldDescriptorProto, str]]:
        """
        遍历文件级扩展（顶层扩展 + 嵌套扩展）
        """
        for ext in self.fd.extension:
            yield ext, "file"
        for msg in self.fd.message_type:
            yield from self._iter_msg_extensions(msg, prefix=msg.name)

    def _iter_msg_extensions(self, msg: DescriptorProto, prefix: str) -> Iterator[Tuple[FieldDescriptorProto, str]]:
        for ext in msg.extension:
            yield ext, prefix
        for nested in msg.nested_type:
            yield from self._iter_msg_extensions(nested, prefix=f"{prefix}.{nested.name}")
